/**
 * 字符串扩展, 这些工具类方法注册到了全局对象STR_UTIL中.
 */
;(function(winObj) {

    const WIN = winObj ? winObj : window;

    const VERSION = "v1.0";

    let _config = {
        frontGetThrowError: true    // 控制frontGet方法无参数时是否抛出异常
    };

    const STR_UTIL = {
        /**
         * 功能: 获取版本号
         * @returns {string}
         */
        version: function () {
            return VERSION;
        },
        /**
         * 功能: 判断对象是否为无效
         * @param text          判断的对象
         * @returns {boolean}   true: 无效, false: 有效
         */
        isEmpty: function (value) {
            if (typeof value === "undefined" || value === null) {
                return true;
            }

            if (typeof value === "string") {
                return value === "";
            }

            if (value instanceof Array) {
                return value.length === 0;
            }

            return false;
        },
        /**
         * 功能: 判断字符串是否非空
         * @param text          判断的字符串
         * @returns {boolean}   true: 有效, false: 无效
         */
        isNotEmpty: function (text) {
            return !this.isEmpty(text);
        },
        /**
         * 功能: 该函数可以接收任意多个参数, 越前面的优先级越高, 不传入参数将会抛出异常
         * @returns {*}
         */
        frontGet: function () {
            if (arguments.length === 0) {
                if (!_config.frontGetThrowError) {
                    console.log("该函数参数不能为空");
                    return;
                }
                throw new Error("The number of parameters of this function must be greater than 0");

            }
            let validVal = arguments[0];
            for (let index in arguments) {
                if (this.isNotEmpty(arguments[index])) {
                    validVal = arguments[index];
                    break;
                }
            }
            return validVal;
        },
        /**
         * 功能: 通过函数提供外界修改配置项, 决定frontGet函数在没有参数时是否抛出异常.
         * @param flag
         */
        frontGetThrowError: function (flag) {
            _config.frontGetThrowError = flag;
        },
        /**
         * 功能: 如果`value1`有效, 就返回value1的值, 反之返回value2的值.
         * 备注: 仿oracle的nvl函数
         */
        nvl: function (value1, value2) {
            if (this.isNotEmpty(value1)) {
                return value1;
            }
            return value2;
        },
        /**
         * 功能: 对传入的参数进行转换, 参考oracle的decode函数
         */
        decode: function () {
            if (arguments.length < 4) {
                throw new Error("decode函数的参数最少为4个!");
            }
            if (arguments.length % 2 !== 0) {
                throw new Error("decode函数的参数个数只能是偶数个!");
            }

            const baseVal = arguments[0];
            const endVal = arguments[arguments.length - 1];

            for (let i = 1; i <= arguments.length - 2; i += 2) {
                if (arguments[i] === baseVal) {
                    return arguments[i + 1];
                }
            }

            return endVal;
        },
        /**
         * 功能: 生成指定长度和基数的uuid
         * @param len       长度
         * @param radix     基数
         */
        uuid: function (len, radix) {
            var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
            var uuid = [],
                i;
            radix = radix || chars.length;

            if (len) {
                // Compact form
                for (i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * radix];
            } else {
                // rfc4122, version 4 form
                var r;

                // rfc4122 requires these characters
                uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
                uuid[14] = '4';

                // Fill in random data.  At i==19 set the high bits of clock sequence as
                // per rfc4122, sec. 4.1.5
                for (i = 0; i < 36; i++) {
                    if (!uuid[i]) {
                        r = 0 | Math.random() * 16;
                        uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r];
                    }
                }
            }

            return uuid.join('');
        }
    };

    WIN.STR_UTIL = STR_UTIL;

}.call(this));